package me.yangbajing.web
package snippet

import scala.xml.{Text, NodeSeq}

import net.liftweb.http.{S, SHtml, DispatchSnippet}
import net.liftweb.util.Helpers._
import net.liftweb.util.CssSel

import yangbajing.util.Imports.Y

import me.yangbajing.model.{Account, MDocument, MCategory}
import net.liftweb.common.{Failure, Full}
import net.liftweb.http.js.JsCmds

object CategorySnippet extends DispatchSnippet {
  def dispatch = {
    case "categories" => categories
    case "datas" => datas
    case "detail" => detail
  }

  def categories(nodeSeq: NodeSeq): NodeSeq = {
    val author = S.attr("author") or W.reqDocument.is.map(_.creator)
    val vs = MCategory.idNames()

    val cssSel =
      "li" #> vs.map {
        case (id, name) =>
          ".badge *" #> MDocument.size(categoryId = Some(id), creator = author) &
            "href=category [href]" #> W.hrefCategory(name) &
            "href=category *" #> name
      }

    cssSel(nodeSeq)
  }

  def datas(nodeSeq: NodeSeq): NodeSeq = {
    val curPage = H.param("cur_page", 1)
    val limit = H.param("limit", H.defaultLimit)
    val creator = H.param("creator")

    val page = MCategory.pagination(curPage, limit, creator = creator)

    val cssSel =
      "#category-total *" #> page.total &
        "#category-datas tr" #> page.page.map {
          category =>
            val removeElem =
              H.actionDialog(nextFuncName, Text("删除"), Text("删除分类"), Text("确认删除分类：" + category.name)) {
                MCategory.removeById(category.id)
                $("#" + category.id).remove().cmd
              }

            <tr id={category.id}>
              <td>
                {H.href(W.hrefCategory(category.name), category.id)}
              </td>
              <td>
                {H.href(W.hrefCategory(category.name), category.name)}
              </td>
              <td>
                {H.href(W.hrefCategory(category.name), category.creator)}
              </td>
              <td>
                {H.href(W.hrefCategory(category.name), Y.formatDateTime print category.created_at)}
              </td>
              <td>
                {removeElem}
              </td>
            </tr>
        } &
        "#category-pagination" #> page.pagination("")

    cssSel(nodeSeq)
  }

  def detail(nodeSeq: NodeSeq): NodeSeq = {
    val cssSel =
      for {
        account <- W.theAccount.is ?~ "账户会话不存在"
      } yield _detail(account)

    cssSel map (_ apply nodeSeq) openOr NodeSeq.Empty
  }

  private def _detail(account: Account): CssSel = {
    val category = W.reqCategory.is
    var name = W.reqCategory.is.map(_.name) openOr ""

    "data-name=id [value]" #> W.reqCategory.is.map(_.id).openOr("") &
      "@name" #> SHtml.text(name, name = _) &
      "data-name=creator [value]" #> W.reqCategory.is.map(_.creator).openOr("") &
      "data-name=created-at [value]" #> W.reqCategory.is.map(Y.formatDateTime print _.created_at).openOr("") &
      "@submit" #> SHtml.hidden(() =>
        category match {
          case Full(c) => // edit
            MCategory.modify(c.id, name) match {
              case Full(1) => JsCmds.Alert("编辑分类成功") & JsCmds.RedirectTo(W.hrefCategory(c.name))
              case Failure(msg, _, _) => JsCmds.Alert("编辑分类失败: " + msg)
              case _ => JsCmds.Alert("编辑分类失败")
            }

          case _ => // insert
            MCategory.insert(name, account.id) match {
              case Full(c) => JsCmds.Alert("创建分类成功") & JsCmds.RedirectTo(W.hrefCategory(c.name))
              case Failure(msg, _, _) => JsCmds.Alert("创建分类失败: " + msg)
              case _ => JsCmds.Alert("创建分类失败")
            }
        })
  }

}
